using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using DnsService.Events;
using DnsService.Models;

namespace DnsService.Interfaces
{
    /// <summary>
    /// DNS服务接口
    /// 定义DNS服务的核心功能
    /// 作者：huobing
    /// </summary>
    public interface IDnsService : global::System.IDisposable
    {
        /// <summary>
        /// 获取服务是否正在运行
        /// </summary>
        bool IsRunning { get; }
        
        /// <summary>
        /// 获取监听端口
        /// </summary>
        int Port { get; }
        
        /// <summary>
        /// 获取DNS缓存记录
        /// </summary>
        Dictionary<string, DnsCacheItem> DnsCache { get; }
        
        /// <summary>
        /// 获取DNS缓存统计信息
        /// </summary>
        DnsCacheStatistics CacheStatistics { get; }
        
        /// <summary>
        /// DNS请求处理事件
        /// </summary>
        event EventHandler<DnsRequestEventArgs>? DnsRequestProcessed;
        
        /// <summary>
        /// 服务状态变化事件
        /// </summary>
        event EventHandler<DnsServiceStatusEventArgs>? StatusChanged;
        
        /// <summary>
        /// 启动DNS服务
        /// </summary>
        /// <returns>是否启动成功</returns>
        bool Start();
        
        /// <summary>
        /// 停止DNS服务
        /// </summary>
        void Stop();
        
        /// <summary>
        /// 添加DNS记录（快速模式）
        /// </summary>
        /// <param name="domain">域名</param>
        /// <param name="ip">IP地址</param>
        /// <returns>是否添加成功</returns>
        bool AddDnsRecord(string domain, string ip);
        
        /// <summary>
        /// 添加DNS记录（完整模式）
        /// </summary>
        /// <param name="domain">域名</param>
        /// <param name="ip">IP地址</param>
        /// <param name="recordType">记录类型</param>
        /// <param name="ttl">生存时间</param>
        /// <param name="description">记录描述</param>
        /// <returns>是否添加成功</returns>
        bool AddDnsRecord(string domain, string ip, string recordType, int ttl, string description);
        
        /// <summary>
        /// 移除DNS记录
        /// </summary>
        /// <param name="domain">域名</param>
        /// <param name="recordType">记录类型</param>
        /// <returns>是否移除成功</returns>
        bool RemoveDnsRecord(string domain, string recordType = "A");
        
        /// <summary>
        /// 清除所有DNS记录
        /// </summary>
        void ClearDnsRecords();
        
        /// <summary>
        /// 获取所有DNS记录
        /// </summary>
        /// <returns>DNS记录列表</returns>
        List<DnsRecord> GetDnsRecords();
        
        /// <summary>
        /// 获取DNS记录统计信息
        /// </summary>
        /// <returns>记录统计信息</returns>
        DnsRecordStatistics GetDnsRecordStatistics();
        
        /// <summary>
        /// 添加DNS缓存项
        /// </summary>
        /// <param name="domain">域名</param>
        /// <param name="cacheItem">DNS缓存项</param>
        /// <returns>是否添加成功</returns>
        bool AddDnsCacheItem(string domain, DnsService.Models.DnsCacheItem cacheItem);
        
        /// <summary>
        /// 移除DNS缓存项
        /// </summary>
        /// <param name="domain">域名</param>
        /// <returns>是否移除成功</returns>
        bool RemoveDnsCacheItem(string domain);
        
        /// <summary>
        /// 清除所有DNS缓存
        /// </summary>
        void ClearDnsCache();
        
        /// <summary>
        /// 清理过期缓存
        /// </summary>
        /// <returns>清理的缓存项数量</returns>
        int CleanExpiredCache();
        
        /// <summary>
        /// 获取缓存命中率
        /// </summary>
        /// <returns>命中率百分比</returns>
        double GetCacheHitRate();
        
        /// <summary>
        /// 获取上游DNS信息（用于展示）
        /// </summary>
        /// <returns>上游DNS信息列表</returns>
        System.Collections.Generic.List<DnsService.Models.UpstreamDnsInfo> GetUpstreamDnsInfos();
        
        /// <summary>
        /// 导出DNS记录到文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <returns>是否导出成功</returns>
        bool ExportDnsRecords(string filePath);
        
        /// <summary>
        /// 从文件导入DNS记录
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <returns>是否导入成功</returns>
        bool ImportDnsRecords(string filePath);
        
        /// <summary>
        /// 测试DNS服务器连接
        /// </summary>
        /// <param name="dnsServer">DNS服务器地址</param>
        /// <param name="timeout">超时时间（毫秒）</param>
        /// <returns>测试结果</returns>
        Task<DnsTestResult> TestDnsServerAsync(string dnsServer, int timeout = 5000);

        /// <summary>
        /// 更新上游DNS优先级（将指定列表置于首位，保留原有其他并去重）
        /// </summary>
        /// <param name="preferred">首选的上游DNS服务器列表；允许为 null（视为不变更）。</param>
        void UpdatePreferredUpstreamDnsServers(IEnumerable<string>? preferred);

        /// <summary>
        /// 根据上游DNS服务器IP清除缓存（清除由这些上游DNS产生的域名缓存）
        /// </summary>
        /// <param name="dnsServers">上游DNS服务器列表；允许为 null（视为不清理）。</param>
        void ClearCacheByUpstreamDnsServers(IEnumerable<string>? dnsServers);
    }
    
    /// <summary>
    /// DNS配置管理器接口
    /// 作者：huobing
    /// </summary>
    public interface IDnsConfigManager : IDisposable
    {
        /// <summary>
        /// 获取当前配置对象
        /// </summary>
        DnsServiceConfig Config { get; }
        
        /// <summary>
        /// 加载配置
        /// </summary>
        /// <returns>DNS服务配置</returns>
        DnsServiceConfig LoadConfig();
        
        /// <summary>
        /// 保存配置
        /// </summary>
        /// <param name="config">DNS服务配置</param>
        void SaveConfig(DnsServiceConfig config);
        
        /// <summary>
        /// 获取设置值
        /// </summary>
        /// <param name="key">设置键</param>
        /// <param name="defaultValue">默认值</param>
        /// <returns>设置值</returns>
        string GetSetting(string key, string defaultValue = "");
        
        /// <summary>
        /// 保存设置值
        /// </summary>
        /// <param name="key">设置键</param>
        /// <param name="value">设置值</param>
        void SaveSetting(string key, string value);
        
        /// <summary>
        /// 获取本地DNS服务端口
        /// </summary>
        /// <returns>端口号</returns>
        int GetLocalDnsPort();
        
        /// <summary>
        /// 设置本地DNS服务端口
        /// </summary>
        /// <param name="port">端口号</param>
        /// <returns>是否设置成功</returns>
        bool SetLocalDnsPort(int port);
        
        /// <summary>
        /// 获取上游DNS服务器列表
        /// </summary>
        /// <returns>DNS服务器列表</returns>
        List<string> GetUpstreamDnsServers();
        
        /// <summary>
        /// 添加上游DNS服务器
        /// </summary>
        /// <param name="dnsServer">DNS服务器地址</param>
        /// <returns>是否添加成功</returns>
        bool AddUpstreamDnsServer(string dnsServer);
        
        /// <summary>
        /// 移除上游DNS服务器
        /// </summary>
        /// <param name="dnsServer">DNS服务器地址</param>
        /// <returns>是否移除成功</returns>
        bool RemoveUpstreamDnsServer(string dnsServer);
        
        /// <summary>
        /// 获取DNS记录字典
        /// </summary>
        /// <returns>DNS记录字典</returns>
        Dictionary<string, DnsRecord> GetDnsRecords();
        
        /// <summary>
        /// 添加DNS记录
        /// </summary>
        /// <param name="domain">域名</param>
        /// <param name="ip">IP地址</param>
        /// <param name="recordType">记录类型</param>
        /// <param name="ttl">生存时间</param>
        /// <param name="description">描述信息</param>
        /// <returns>是否添加成功</returns>
        bool AddDnsRecord(string domain, string ip, string recordType = "A", int ttl = 3600, string description = "");
        
        /// <summary>
        /// 移除DNS记录
        /// </summary>
        /// <param name="domain">域名</param>
        /// <returns>是否移除成功</returns>
        bool RemoveDnsRecord(string domain);
        
        /// <summary>
        /// 获取是否启用DNS缓存
        /// </summary>
        /// <returns>是否启用缓存</returns>
        bool GetEnableCache();
        
        /// <summary>
        /// 设置是否启用DNS缓存
        /// </summary>
        /// <param name="enable">是否启用</param>
        /// <returns>是否设置成功</returns>
        bool SetEnableCache(bool enable);
        
        /// <summary>
        /// 获取缓存过期时间（分钟）
        /// </summary>
        /// <returns>缓存过期时间</returns>
        int GetCacheExpirationMinutes();
        
        /// <summary>
        /// 设置缓存过期时间（分钟）
        /// </summary>
        /// <param name="minutes">过期时间</param>
        /// <returns>是否设置成功</returns>
        bool SetCacheExpirationMinutes(int minutes);
        
        /// <summary>
        /// 获取默认DNS记录TTL（秒）
        /// </summary>
        /// <returns>默认TTL值</returns>
        int GetDefaultRecordTtl();
        
        /// <summary>
        /// 设置默认DNS记录TTL（秒）
        /// </summary>
        /// <param name="ttl">TTL值（秒）</param>
        /// <returns>是否设置成功</returns>
        bool SetDefaultRecordTtl(int ttl);
        
        
        /// <summary>
        /// 重置为默认配置
        /// </summary>
        /// <returns>是否重置成功</returns>
        bool ResetToDefaults();
        
        /// <summary>
        /// 开始监听配置文件变更
        /// </summary>
        void StartWatching();
        
        /// <summary>
        /// 停止监听配置文件变更
        /// </summary>
        void StopWatching();
        
        /// <summary>
        /// 配置文件变更事件
        /// </summary>
        event EventHandler ConfigFileChanged;
    }
}